package com.xyzwps.server.paimon.jackson

import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.core.JsonToken
import com.fasterxml.jackson.databind.DeserializationContext
import com.fasterxml.jackson.databind.JsonMappingException
import com.fasterxml.jackson.databind.KeyDeserializer
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.deser.std.StdDeserializer
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.databind.ser.std.StdSerializer
import com.xyzwps.server.paimon.value.UserId

class UserIdJacksonSerializer : StdSerializer<UserId>(UserId::class.java) {
    override fun serialize(value: UserId?, gen: JsonGenerator, provider: SerializerProvider) {
        if (value == null) {
            gen.writeNull()
        } else {
            gen.writeString(value.value.toString())
        }
    }
}

class UserIdJacksonDeserializer : StdDeserializer<UserId>(UserId::class.java) {
    override fun deserialize(p: JsonParser, ctxt: DeserializationContext): UserId? =
        when (val token = p.currentToken) {
            JsonToken.VALUE_NULL -> null
            JsonToken.VALUE_STRING -> UserId(p.text.toLong())
            JsonToken.VALUE_NUMBER_INT -> UserId(p.longValue)
            else -> throw JsonMappingException.from(p, "Unexpected token $token")
        }
}

class UserIdJacksonKeyDeserializer : KeyDeserializer() {
    override fun deserializeKey(key: String?, ctxt: DeserializationContext): Any? =
        if (key == null) null else UserId(key.toLong())
}

fun SimpleModule.registerUserId() {
    addSerializer(UserId::class.java, UserIdJacksonSerializer())
    addDeserializer(UserId::class.java, UserIdJacksonDeserializer())
    addKeySerializer(UserId::class.java, UserIdJacksonSerializer())
    addKeyDeserializer(UserId::class.java, UserIdJacksonKeyDeserializer())
}